package org.softmed.filehandling.selectors;

import groovy.lang.GroovyClassLoader;
import java.io.File;
import java.io.InputStream;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.softmed.filehandling.FileUtil;

/**
 * It will select groovy class files
 * 
 * @author guilherme
 * 
 */
public class GroovyFileSelector implements FileSelector {

	static GroovyClassLoader groovyClassLoader;

	ClassLoader parent;

	InputStream inStream;
	// Class groovyClass;
	FileUtil util = new FileUtil();

	// String path;

	public GroovyFileSelector() {
		// parent = getClass().getClassLoader();
		// loader = new GroovyClassLoader(parent);
		// loader.setShouldRecompile(true);
	}

	@Override
	public Class processFile(String fileName, String pckgname) throws Throwable {

		Class[] loadedClasses = groovyClassLoader.getLoadedClasses();
		for (int i = 0; i < loadedClasses.length; i++) {
			Class class1 = loadedClasses[i];
			// System.out.println(class1);
		}

		// TODO change this way of getting the real path
		FileUtil util = new FileUtil();
		String path = pckgname.replace('.', '/');
		path += '/' + fileName;

		String filePath = util.fixPath(path);

		if (filePath == null)
			throw new RuntimeException("Could not find file named " + fileName
					+ " with .groovy nor .gc extension in package " + pckgname);

		File file = util.getFile(filePath);
		// loader.setShouldRecompile(true);
		// loader.clearCache();

		String groovyClassCode = util.readFromFile(file);
		try {
			GroovyClassLoader temp = new GroovyClassLoader(groovyClassLoader);
			Class test = temp.parseClass(groovyClassCode);

			try {
				Class exists = groovyClassLoader.loadClass(test
						.getCanonicalName());
				// System.out.println("Class " + test.getCanonicalName()
				// + " already loaded in the class loader");
				return exists;
			} catch (Throwable t) {
				// t.printStackTrace();

				Class type = groovyClassLoader.parseClass(groovyClassCode);
				return type;

			}
		} catch (Throwable t) {
			System.err.println("Eror compiling groovy class " + file.getName());
			System.err.println("Full Path of Groovy Class : "
					+ file.getCanonicalPath());

			throw t;
		}

		// return groovyClass;
	}

	@Override
	public boolean isFileSelected(String filePath, String pckgname) {
		if (filePath.endsWith(".groovy") || filePath.endsWith(".gc"))
			return true;
		else
			return false;
	}

	public static GroovyClassLoader getGroovyClassLoader() {
		return groovyClassLoader;
	}

	public static void setGroovyClassLoader(GroovyClassLoader loader) {
		GroovyFileSelector.groovyClassLoader = loader;
	}

	@Override
	public Class processJarFile(JarFile jarFile, JarEntry jarEntry, String path)
			throws Throwable {
		String jarName = jarEntry.getName();
		if (jarName.endsWith(".groovy") || jarName.endsWith(".gc")) {
			String className = jarName.replaceAll("/", ".");
			// className = className.replace(".class", "");
			// util.getFile(path);
			System.out.println("GroovyFileSelector: path: " + path
					+ " className " + className);
			Class type = processFile(path, className);

			return type;
		}

		return null;
	}

}
